home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*------------------------------------------------------------------------------
- * Vroom Track Compiler
- *----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <strings.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <math.h>
-
-
- #define STRAIGHT_TRACK (0)
- #define L_CURVE_TRACK (1)
- #define R_CURVE_TRACK (2)
- #define MERGE_IN_TRACK (3)
- #define MERGE_OUT_TRACK (4)
- #define MERGE_TRACK MERGE_IN_TRACK
- #define MAX_COURSE_SIZE (150)
- #define OPTIMAL_STRAIGHT_LENGTH (800.0f)
- #define MINIMAL_STRAIGHT_LENGTH (0.75f*OPTIMAL_STRAIGHT_LENGTH)
- #define MIN_RADIUS (300.0f)
- #define LANE_WIDTH (75.0f)
-
-
- typedef struct {
- char id[4] ;
- float data[8] ;
- } TrackDetailQuad ;
-
-
- /* BEGIN PROTOTYPES -S vtc.c */
- static void addCurvedTrack( int token, int nLanes, float angle,
- float radius ) ;
- static void addMergeInTrack( int nLanes, float length ) ;
- static void addMergeOutTrack( int nLanes, float length ) ;
- static void addStraightTrack( int nLanes, float length ) ;
- static void addTrackToken( int token, float arg1, float arg2 ) ;
- static void checkLanes( int nLanes ) ;
- static void compileTrack( char *inName, char *outName ) ;
- static void myWrite( int fd, void *p, int size ) ;
- /* END PROTOTYPES -S vtc.c */
-
-
- static TrackDetailQuad details[MAX_COURSE_SIZE/4] ;
-
-
-
- static char *trackNames[] = {
- "STRAIGHT_TRACK",
- "L_CURVE_TRACK",
- "R_CURVE_TRACK",
- "MERGE_TRACK",
- } ;
- static int trackNameSize[] = {
- 14,
- 13,
- 13,
- 11,
- } ;
-
- static char *basename ;
- static int nTrack = 0 ;
- static int lastNLanes ;
- static int nLine = 0 ;
-
- int
- main(
- int argc,
- char **argv
- )
- {
- /*
- * Get basename.
- */
- if( ( basename = strrchr( argv[0], '/' ) ) == NULL )
- basename = argv[0] ;
- else
- basename++ ;
-
- if( argc != 3 )
- {
- fprintf( stderr, "Usage: %s track_src out_track.vct\n",
- basename ) ;
- exit( 1 ) ;
- }
-
- compileTrack( argv[1], argv[2] ) ;
-
- exit( 0 ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Compile an ascii track description into an optimized binary one.
- *----------------------------------------------------------------------------*/
- static void
- compileTrack(
- char *inName,
- char *outName
- )
- {
- FILE *in ;
- int out ;
- int i ;
- int n ;
- char line[256] ;
- int nLaps ;
- int nLanes ;
- float length ;
- float angle ;
- float radius ;
-
- if( ( in = fopen( inName, "r" ) ) == NULL )
- {
- fprintf( stderr, "%s: could not open %s\n", basename, inName ) ;
- exit( 1 ) ;
- }
-
- if( ( out = open( outName, O_WRONLY | O_CREAT | O_TRUNC, 0644 ) ) < 0 )
- {
- perror( basename ) ;
- exit( 1 ) ;
- }
-
- do {
- if( fgets( line, sizeof( line ), in ) == NULL )
- {
- perror( inName ) ;
- }
- nLine++ ;
- } while( line[0] == '#' ) ;
-
- nLaps = atoi( line ) ;
-
- if( nLaps < 0 || nLaps > 99 )
- {
- fprintf( stderr, "%s: number of laps must be between 1 and 99,"
- " inclusive\n", basename ) ;
- exit( 1 ) ;
- }
-
- myWrite( out, &nLaps, sizeof( nLaps ) ) ;
-
- while( fgets( line, sizeof( line ), in ) != NULL )
- {
- nLine++ ;
- if( line[0] == '#' )
- {
- continue ;
- }
-
- for( i = 0 ; i < sizeof( trackNames ) / sizeof( trackNames[0] );
- i++ )
- {
- if( !strncmp( line, trackNames[i], trackNameSize[i] ) )
- break ;
- }
-
- if( nTrack == 0 && i != STRAIGHT_TRACK )
- {
- fprintf( stderr, "%s: first track piece must be a "
- "straight piece\n", basename ) ;
- exit( 1 ) ;
- }
-
- switch( i )
- {
- case STRAIGHT_TRACK :
- if( sscanf( line, "%*s %d %f", &nLanes,
- &length ) != 2 )
- {
- fprintf( stderr, "%s: error reading "
- "line %d of %s\n", basename,
- nLine, inName ) ;
- exit( 1 ) ;
- }
- addStraightTrack( nLanes, length ) ;
- break ;
-
- case MERGE_TRACK :
- if( sscanf( line, "%*s %d %f", &nLanes,
- &length ) != 2 )
- {
- fprintf( stderr, "%s: error reading "
- "line %d of %s\n", basename,
- nLine, inName ) ;
- exit( 1 ) ;
- }
- if( nLanes < lastNLanes )
- {
- addMergeInTrack( nLanes, length ) ;
- }
- else
- {
- addMergeOutTrack( nLanes, length ) ;
- }
- break ;
-
- case L_CURVE_TRACK :
- case R_CURVE_TRACK :
- if( sscanf( line, "%*s %d %f %f", &nLanes,
- &angle, &radius ) != 3 )
- {
- fprintf( stderr, "%s: error reading "
- "line %d of %s\n", basename,
- nLine, inName ) ;
- exit( 1 ) ;
- }
- addCurvedTrack( i, nLanes, angle, radius ) ;
- break ;
-
- default :
- fprintf( stderr, "%s: unknown track type at "
- "line %d of %s\n", basename,
- nLine, inName ) ;
- exit( 1 ) ;
- break ;
- }
- }
-
- myWrite( out, &nTrack, sizeof( nTrack ) ) ;
- myWrite( out, details, sizeof( details[0] ) * ( nTrack + 3 ) / 4 ) ;
-
- printf( "%s contains %d pieces of track (%d maximum)\n", outName,
- nTrack, MAX_COURSE_SIZE ) ;
- fclose( in ) ;
- close( out ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Error checking write function.
- *----------------------------------------------------------------------------*/
- static void
- myWrite(
- int fd,
- void *p,
- int size
- )
- {
- if( write( fd, p, size ) != size )
- {
- perror( basename ) ;
- exit( 1 ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Add a stretch of straight track.
- *----------------------------------------------------------------------------*/
- static void
- addStraightTrack(
- int nLanes,
- float length
- )
- {
- int ns ;
- float dl ;
-
- checkLanes( nLanes ) ;
-
- if( length < MINIMAL_STRAIGHT_LENGTH )
- {
- fprintf( stderr, "%s: straight section at line %d too short -- "
- "must be at least %.1f units\n", basename,
- nLine, MINIMAL_STRAIGHT_LENGTH ) ;
- exit( 1 ) ;
- }
-
- if( length >= 2.0f * MINIMAL_STRAIGHT_LENGTH )
- {
- ns = (int)( length / OPTIMAL_STRAIGHT_LENGTH + 0.5f ) ;
- dl = length / (float)ns ;
- }
- else
- {
- ns = 1 ;
- dl = length ;
- }
-
- printf( "line %2d: %d straights of length %.1f\n", nLine, ns, dl ) ;
- while( ns-- )
- {
- addTrackToken( STRAIGHT_TRACK, (float)nLanes, dl ) ;
- }
-
- lastNLanes = nLanes ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Add a stretch of merge in track.
- *----------------------------------------------------------------------------*/
- static void
- addMergeInTrack(
- int nLanes,
- float length
- )
- {
- int ns ;
- float dl ;
-
- checkLanes( nLanes + 2 ) ;
-
- if( length < MINIMAL_STRAIGHT_LENGTH )
- {
- fprintf( stderr, "%s: merge section at line %d too short -- "
- "must be at least %.1f units\n", basename,
- nLine, MINIMAL_STRAIGHT_LENGTH ) ;
- exit( 1 ) ;
- }
-
- if( length >= 2.0f * MINIMAL_STRAIGHT_LENGTH )
- {
- ns = (int)( length / OPTIMAL_STRAIGHT_LENGTH + 0.5f ) ;
- dl = length / (float)ns ;
- }
- else
- {
- ns = 1 ;
- dl = length ;
- }
-
- printf( "line %2d: 1 merge-in of length %.1f\n", nLine, dl ) ;
- addTrackToken( MERGE_IN_TRACK, (float)nLanes, dl ) ;
- ns-- ;
-
- if( ns > 0 )
- {
- printf( "line %2d: %d straights-in of length %.1f\n", nLine,
- ns, dl ) ;
- while( ns-- )
- {
- addTrackToken( STRAIGHT_TRACK, (float)nLanes, dl ) ;
- }
- }
-
- lastNLanes = nLanes ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Add a stretch of merge out track.
- *----------------------------------------------------------------------------*/
- static void
- addMergeOutTrack(
- int nLanes,
- float length
- )
- {
- int ns ;
- float dl ;
-
- checkLanes( nLanes - 2 ) ;
-
- if( length < MINIMAL_STRAIGHT_LENGTH )
- {
- fprintf( stderr, "%s: merge section at line %d too short -- "
- "must be at least %.1f units\n", basename,
- nLine, MINIMAL_STRAIGHT_LENGTH ) ;
- exit( 1 ) ;
- }
-
- if( length >= 2.0f * MINIMAL_STRAIGHT_LENGTH )
- {
- ns = (int)( length / OPTIMAL_STRAIGHT_LENGTH + 0.5f ) ;
- dl = length / (float)ns ;
- }
- else
- {
- ns = 1 ;
- dl = length ;
- }
-
- printf( "line %2d: %d merge-outs of length %.1f\n", nLine, ns, dl ) ;
- while( ns-- )
- {
- addTrackToken( MERGE_OUT_TRACK, (float)nLanes, dl ) ;
- }
-
- lastNLanes = nLanes ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Add a stretch of curved track.
- *----------------------------------------------------------------------------*/
- static void
- addCurvedTrack(
- int token,
- int nLanes,
- float angle,
- float radius
- )
- {
- int ns ;
- float da ;
- float length ;
- float minRad ;
-
- checkLanes( nLanes ) ;
-
- minRad = radius - 0.5f * ( nLanes - 1 ) * LANE_WIDTH ;
-
- angle = fmodf( angle, 360.0f ) ;
- if( angle <= 0.0f )
- {
- fprintf( stderr, "%s: must specify a curve angle greater than "
- "0.0 (line %d)\n", basename, nLine ) ;
- exit( 1 ) ;
- }
-
- if( minRad < MIN_RADIUS )
- {
- fprintf( stderr, "%s: curve radius for %d lanes must be %.0f "
- "or greater (line %d)\n", basename, nLanes,
- MIN_RADIUS + 0.5f * ( nLanes - 1 ) * LANE_WIDTH,
- nLine ) ;
- exit( 1 ) ;
- }
-
- length = 2.0f * minRad * angle * M_PI / 180.0f ;
-
- if( length < MINIMAL_STRAIGHT_LENGTH )
- {
- fprintf( stderr, "%s: curve section at line %d too short -- "
- "must be at least %.1f units\n", basename,
- nLine, MINIMAL_STRAIGHT_LENGTH ) ;
- exit( 1 ) ;
- }
-
- if( length >= 2.0f * MINIMAL_STRAIGHT_LENGTH )
- {
- ns = (int)( length / OPTIMAL_STRAIGHT_LENGTH + 0.5f ) ;
- da = angle / (float)ns ;
- }
- else
- {
- ns = 1 ;
- da = angle ;
- }
- printf( "line %2d: %d curves of angle %.1f\n", nLine, ns, da ) ;
-
- while( ns-- )
- {
- addTrackToken( token, (float)nLanes * 360.0f + da, radius ) ;
- }
-
- lastNLanes = nLanes ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Check that the number of lanes are correct.
- *----------------------------------------------------------------------------*/
- static void
- checkLanes(
- int nLanes
- )
- {
- if( nTrack != 0 && nLanes != lastNLanes )
- {
- fprintf( stderr, "%s: bad number of lanes at line %d\n",
- basename, nLine ) ;
- exit( 1 ) ;
- }
-
- if( nLanes != 2 && nLanes != 4 && nLanes != 6 )
- {
- fprintf( stderr, "%s: number of lanes must be 1, 2, 4, or 6 "
- "(line %d)\n", basename, nLine ) ;
- exit( 1 ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Add a track token and arguments to the list.
- *----------------------------------------------------------------------------*/
- static void
- addTrackToken(
- int token,
- float arg1,
- float arg2
- )
- {
- int dp ;
- int k ;
-
- if( nTrack >= MAX_COURSE_SIZE )
- {
- fprintf( stderr, "%s: course too large by line %d -- reduce "
- "the length\n", basename, nLine ) ;
- exit( 1 ) ;
- }
-
- dp = nTrack / 4 ;
- k = nTrack % 4 ;
- details[dp].id[k] = (char)token ;
- k += k ;
- details[dp].data[k] = arg1 ;
- details[dp].data[k+1] = arg2 ;
-
- nTrack++ ;
- }
-